import sys
import serial
import struct
import time
import datetime
from enum import Enum
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout,
                             QHBoxLayout, QLabel, QPushButton, QLineEdit, QComboBox,
                             QGroupBox, QGridLayout, QCheckBox, QSpinBox, QDoubleSpinBox,
                             QTextEdit, QMessageBox, QFormLayout, QStatusBar, QFrame,
                             QScrollArea, QSizePolicy)
from PyQt5.QtCore import QThread, pyqtSignal, Qt, QTimer, QPropertyAnimation, QEasingCurve, pyqtProperty
from PyQt5.QtGui import QColor, QPainter, QPixmap, QFont, QLinearGradient, QPalette, QBrush, QPen

# 串口配置
SERIAL_PORT = 'COM6'  # 根据实际串口修改
BAUD_RATE = 115200

# 现代化样式表
MODERN_STYLE = """
/* 主窗口样式 */
QMainWindow {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #f8f9fa, stop: 1 #e9ecef);
    color: #212529;
}

/* 标签页样式 */
QTabWidget::pane {
    border: 2px solid #dee2e6;
    border-radius: 8px;
    background: white;
    margin-top: 10px;
}

QTabWidget::tab-bar {
    alignment: center;
}

QTabBar::tab {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #ffffff, stop: 1 #f8f9fa);
    border: 2px solid #dee2e6;
    border-bottom: none;
    border-radius: 8px 8px 0 0;
    padding: 12px 24px;
    margin-right: 2px;
    font-weight: 600;
    font-size: 15px;
    color: #6c757d;
    min-width: 120px;
}

QTabBar::tab:selected {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #4f46e5, stop: 1 #3730a3);
    color: white;
    border-color: #4f46e5;
}

QTabBar::tab:hover:!selected {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #f1f5f9, stop: 1 #e2e8f0);
    color: #4f46e5;
}

/* 组框样式 */
QGroupBox {
    font-weight: 600;
    font-size: 15px;
    color: #374151;
    border: 2px solid #e5e7eb;
    border-radius: 12px;
    margin-top: 15px;
    padding-top: 10px;
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #ffffff, stop: 1 #f9fafb);
}

QGroupBox::title {
    subcontrol-origin: margin;
    left: 15px;
    padding: 5px 15px;
    background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,
                                stop: 0 #4f46e5, stop: 1 #7c3aed);
    color: white;
    border-radius: 8px;
    font-size: 15px;
    font-weight: 700;
}

/* 按钮样式 */
QPushButton {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #4f46e5, stop: 1 #3730a3);
    color: white;
    border: none;
    border-radius: 8px;
    padding: 10px 20px;
    font-weight: 600;
    font-size: 15px;
    min-height: 16px;
}

QPushButton:hover {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #5b47ea, stop: 1 #4338ca);
    transform: translateY(-1px);
}

QPushButton:pressed {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #3730a3, stop: 1 #312e81);
}

QPushButton:disabled {
    background: #9ca3af;
    color: #6b7280;
}

/* 特殊按钮样式 */
QPushButton#successButton {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #10b981, stop: 1 #047857);
}

QPushButton#successButton:hover {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #34d399, stop: 1 #059669);
}

QPushButton#warningButton {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #f59e0b, stop: 1 #d97706);
}

QPushButton#warningButton:hover {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #fbbf24, stop: 1 #f59e0b);
}

QPushButton#dangerButton {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #ef4444, stop: 1 #dc2626);
}

QPushButton#dangerButton:hover {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #f87171, stop: 1 #ef4444);
}

/* 输入框样式 */
QLineEdit, QSpinBox, QDoubleSpinBox, QComboBox {
    border: 2px solid #e5e7eb;
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 15px;
    background: white;
    selection-background-color: #ddd6fe;
}

QLineEdit:focus, QSpinBox:focus, QDoubleSpinBox:focus, QComboBox:focus {
    border-color: #4f46e5;
    background: #fefbff;
}

QComboBox::drop-down {
    border: none;
    width: 20px;
}

QComboBox::down-arrow {
    image: none;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid #6b7280;
    margin-right: 5px;
}

/* 标签样式 */
QLabel {
    color: #374151;
    font-size: 18px;
}

QLabel#valueLabel {
    font-weight: 600;
    font-size: 44px;
    color: #1f2937;
    background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,
                                stop: 0 #f0f9ff, stop: 1 #e0f2fe);
    border: 1px solid #0ea5e9;
    border-radius: 6px;
    padding: 8px 12px;
}

QLabel#statusLabel {
    font-weight: 600;
    padding: 6px 12px;
    border-radius: 6px;
    background: #f3f4f6;
    border: 1px solid #d1d5db;
}

/* 文本编辑器样式 */
QTextEdit {
    border: 2px solid #e5e7eb;
    border-radius: 8px;
    background: #1f2937;
    color: #f9fafb;
    font-family: 'Consolas', 'Monaco', monospace;
    font-size: 15px;
    selection-background-color: #374151;
}

/* 状态栏样式 */
QStatusBar {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #f8fafc, stop: 1 #e2e8f0);
    border-top: 1px solid #cbd5e1;
    color: #475569;
    font-weight: 600;
    padding: 5px;
}

/* 滚动条样式 */
QScrollBar:vertical {
    background: #f1f5f9;
    width: 12px;
    border-radius: 6px;
}

QScrollBar::handle:vertical {
    background: #cbd5e1;
    border-radius: 6px;
    min-height: 20px;
}

QScrollBar::handle:vertical:hover {
    background: #94a3b8;
}
"""


class DeviceType(Enum):
    """设备类型枚举"""
    TEMP_SENSOR = 0x55A1  # 温度传感器
    MOTOR_CONTROLLER = 0x55A2  # PWM控制器
    LED_CONTROLLER = 0x55A3  # LED控制器
    BUTTON_STATUS = 0x55A4  # 按键状态
    SYSTEM_STATUS = 0x55A5  # 系统状态


class CommandType(Enum):
    """命令类型枚举"""
    # 原有的命令
    PERIOD = "Period"
    TOGGLE_D1 = "ToggleD1"
    TOGGLE_D2 = "ToggleD2"
    PWM_SET = "PWMset"
    COUNTER_SET = "Counterset"

    # 新添加的设置检测周期的命令
    SENSOR_TSET = "SensorTset"  # 设置温度传感器检测周期
    PWM_TSET = "PWMTset"  # 设置PWM控制器检测周期
    LED_TSET = "LEDTset"  # 设置LED控制器检测周期
    BUTTON_TSET = "ButtonTset"  # 设置按键状态检测周期
    SYSTEM_TSET = "SystemTset"  # 设置系统状态检测周期


def calculate_crc(data):
    """CRC16 MODBUS 校验算法"""
    crc = 0xFFFF
    for byte in data:
        crc ^= byte
        for _ in range(8):
            if crc & 0x01:
                crc = (crc >> 1) ^ 0xA001
            else:
                crc = crc >> 1
    return crc


def create_data_packet(fields_data):
    """创建数据包

    Args:
        fields_data: 字段数据列表，每个元素为 (type, data) 元组
                    type: 数据类型 (0x01=有符号整型, 0x02=浮点型, 0x03=无符号整型, 0x04=字符串, 0x05=布尔型)
                    data: 实际数据

    Returns:
        完整的数据包字节流
    """
    packet = bytearray()

    # 头部 (2字节) - 0x55AA 大端
    packet.extend([0x55, 0xAA])

    # 总长度 (2字节) - 先占位，后面填写 (小端字节序)
    length_pos = len(packet)
    packet.extend([0x00, 0x00])

    # 字段数 (1字节)
    packet.append(len(fields_data))

    # 添加字段数据
    for field_type, field_data in fields_data:
        packet.append(field_type)  # 字段类型

        if field_type == 0x01:  # 有符号整型
            data_bytes = struct.pack('>i', field_data)
            packet.append(len(data_bytes))  # 数据长度
            packet.extend(data_bytes)

        elif field_type == 0x02:  # 浮点型
            data_bytes = struct.pack('>f', field_data)
            packet.append(len(data_bytes))  # 数据长度
            packet.extend(data_bytes)

        elif field_type == 0x03:  # 无符号整型
            data_bytes = struct.pack('>I', field_data)
            packet.append(len(data_bytes))  # 数据长度
            packet.extend(data_bytes)

        elif field_type == 0x04:  # 字符串
            if isinstance(field_data, str):
                data_bytes = field_data.encode('utf-8')
            else:
                data_bytes = field_data
            packet.append(len(data_bytes))  # 数据长度
            packet.extend(data_bytes)

        elif field_type == 0x05:  # 布尔型
            data_bytes = bytes([1 if field_data else 0])
            packet.append(len(data_bytes))  # 数据长度
            packet.extend(data_bytes)

        else:
            raise ValueError(f"Unsupported field type: {field_type}")

    # 计算总长度（包括CRC 2字节）
    total_length = len(packet) + 2
    packet[length_pos] = total_length & 0xFF  # 小端低字节
    packet[length_pos + 1] = (total_length >> 8) & 0xFF  # 小端高字节

    # 计算CRC
    crc = calculate_crc(packet)
    packet.append(crc & 0xFF)  # CRC低字节
    packet.append((crc >> 8) & 0xFF)  # CRC高字节

    return bytes(packet)


class SerialThread(QThread):
    """串口通信线程"""
    data_received = pyqtSignal(dict)
    log_message = pyqtSignal(str)
    connection_status = pyqtSignal(bool)

    def __init__(self, port, baudrate):
        super().__init__()
        self.port = port
        self.baudrate = baudrate
        self.serial = None
        self.running = False
        self.last_value = None  # 存储上一次发送的值

    def run(self):
        self.running = True
        try:
            self.serial = serial.Serial(self.port, self.baudrate, timeout=1)
            self.log_message.emit(f"🔌 串口 {self.port} 已打开，波特率 {self.baudrate}")
            self.connection_status.emit(True)

            receive_state = 0  # 0=等待头部, 1=接收数据
            buffer = bytearray()
            expected_length = 0

            while self.running:
                try:
                    if self.serial and self.serial.in_waiting > 0:
                        new_data = self.serial.read(self.serial.in_waiting)
                        buffer.extend(new_data)

                        while len(buffer) >= 2:
                            if receive_state == 0:  # 等待头部
                                # 检查是否是有效的设备头部
                                if len(buffer) >= 4:
                                    header = struct.unpack('>H', buffer[:2])[0]

                                    valid_header = False
                                    for device_type in DeviceType:
                                        if device_type.value == header:
                                            valid_header = True
                                            break

                                    if valid_header:
                                        # 读取总长度
                                        expected_length = struct.unpack('<H', buffer[2:4])[0]
                                        if 7 <= expected_length <= 256:  # 合理的长度范围
                                            receive_state = 1
                                        else:
                                            buffer = buffer[1:]  # 移除第一个字节，继续搜索
                                    else:
                                        buffer = buffer[1:]  # 移除第一个字节，继续搜索
                                else:
                                    break  # 等待更多数据

                            elif receive_state == 1:  # 接收数据
                                if len(buffer) >= expected_length:
                                    # 提取完整数据包
                                    packet = buffer[:expected_length]
                                    buffer = buffer[expected_length:]

                                    # 解析数据包
                                    result = self.parse_device_packet(packet)

                                    if result:
                                        self.data_received.emit(result)

                                    # 重置状态
                                    receive_state = 0
                                    expected_length = 0
                                else:
                                    break  # 等待更多数据

                        # 防止缓冲区过大
                        if len(buffer) > 512:
                            buffer = buffer[-256:]
                            receive_state = 0

                    time.sleep(0.01)
                except Exception as e:
                    self.log_message.emit(f"❌ 接收数据异常: {str(e)}")
                    time.sleep(0.5)  # 出错后暂停一下

        except serial.SerialException as e:
            self.log_message.emit(f"❌ 串口错误: {str(e)}")
            self.connection_status.emit(False)
        finally:
            self.close()

    def close(self):
        """关闭串口连接"""
        self.running = False
        if self.serial and self.serial.is_open:
            self.serial.close()
            self.log_message.emit(f"🔌 串口 {self.port} 已关闭")
            self.connection_status.emit(False)

    def send_command(self, command_type, value=None):
        """发送命令"""
        try:
            if value is not None:
                self.last_value = value

            fields = []
            if self.last_value is not None:
                if isinstance(self.last_value, int):
                    if self.last_value < 0:
                        fields.append((0x01, self.last_value))  # 有符号整型
                    else:
                        fields.append((0x03, self.last_value))  # 无符号整型
                elif isinstance(self.last_value, float):
                    fields.append((0x02, self.last_value))  # 浮点型
                elif isinstance(self.last_value, bool):
                    fields.append((0x05, self.last_value))  # 布尔型
                elif isinstance(self.last_value, str):
                    fields.append((0x04, self.last_value))  # 字符串

            # 添加命令字符串
            fields.append((0x04, command_type.value))

            # 创建并发送数据包
            packet = create_data_packet(fields)
            if self.serial and self.serial.is_open:
                self.serial.write(packet)
                self.log_message.emit(
                    f"📤 已发送命令: {command_type.value} ({self.last_value if self.last_value is not None else '无参数'})")
                self.log_message.emit(f"📦 数据包: {packet.hex()}")
            else:
                self.log_message.emit("❌ 错误: 串口未打开")

        except Exception as e:
            self.log_message.emit(f"❌ 发送命令异常: {str(e)}")

    def parse_device_packet(self, packet):
        """解析设备数据包"""
        if len(packet) < 7:  # 最小包长度检查
            return None

        idx = 0

        # 解析数据头
        header = struct.unpack('>H', packet[idx:idx + 2])[0]
        idx += 2

        # 识别设备类型
        device_type = None
        for dt in DeviceType:
            if dt.value == header:
                device_type = dt
                break

        if device_type is None:
            return {
                'error': f"未知设备头部: 0x{header:04X}",
                'raw_data': packet.hex()
            }

        # 解析总长度
        total_length = struct.unpack('<H', packet[idx:idx + 2])[0]
        idx += 2

        if total_length != len(packet):
            return {
                'error': f"数据包长度不匹配: 声明{total_length}, 实际{len(packet)}",
                'device_type': device_type
            }

        # 解析字段数
        field_count = packet[idx]
        idx += 1

        # 解析字段数据
        fields = []
        for i in range(field_count):
            if idx + 2 > len(packet) - 2:  # 确保有足够空间读取字段头和CRC
                break

            field_type = packet[idx]
            field_length = packet[idx + 1]
            idx += 2

            if idx + field_length > len(packet) - 2:  # 确保有足够空间读取字段数据
                break

            field_data = packet[idx:idx + field_length]
            idx += field_length

            parsed_data = self.parse_field_data(field_type, field_data)
            fields.append(parsed_data)

        # 验证CRC
        if idx + 2 <= len(packet):
            received_crc = struct.unpack('<H', packet[idx:idx + 2])[0]
            calculated_crc = calculate_crc(packet[:-2])
            crc_valid = (received_crc == calculated_crc)
        else:
            crc_valid = False

        # 根据设备类型解析具体数据
        parsed_data = {}
        if device_type == DeviceType.TEMP_SENSOR and len(fields) >= 3:
            parsed_data = {
                'temperature': fields[0],  # 温度(浮点型)
                'status': fields[1]  # 状态(布尔型)
            }
        elif device_type == DeviceType.MOTOR_CONTROLLER and len(fields) >= 3:
            parsed_data = {
                'speed': fields[0],  # 速度(有符号整型)
                'counter': fields[1],  # 计数值(有符号整型)
                'enabled': fields[2]  # 使能(布尔型)
            }
        elif device_type == DeviceType.LED_CONTROLLER and len(fields) >= 2:
            parsed_data = {
                'led1': fields[0],  # LED1状态(布尔型)
                'led2': fields[1]  # LED2状态(布尔型)
            }
        elif device_type == DeviceType.BUTTON_STATUS and len(fields) >= 3:
            parsed_data = {
                'button1': fields[0],  # 按键1状态(布尔型)
                'button2': fields[1],  # 按键2状态(布尔型)
                'button3': fields[2]  # 按键3状态(布尔型)
            }
        elif device_type == DeviceType.SYSTEM_STATUS and len(fields) >= 4:
            parsed_data = {
                'uptime': fields[0],  # 运行时间(无符号整型)
                'cpu_temp': fields[1],  # CPU温度(有符号整型)
                'system_clock': fields[2],  # 系统时钟(无符号整型)
                'system_ok': fields[3]  # 系统状态(布尔型)
            }

        return {
            'device_type': device_type,
            'data': parsed_data,
            'crc_valid': crc_valid
        }

    def parse_field_data(self, field_type, field_data):
        """解析字段数据"""
        if field_type == 0x01:  # 有符号整型
            if len(field_data) == 4:
                return struct.unpack('>i', field_data)[0]
            return None
        elif field_type == 0x02:  # 浮点型
            if len(field_data) == 4:
                return struct.unpack('>f', field_data)[0]
            return None
        elif field_type == 0x03:  # 无符号整型
            if len(field_data) == 4:
                return struct.unpack('>I', field_data)[0]
            return None
        elif field_type == 0x04:  # 字符串
            return field_data.rstrip(b'\x00').decode('utf-8', errors='replace')
        elif field_type == 0x05:  # 布尔型
            if len(field_data) == 1:
                return bool(field_data[0])
            return None
        return field_data.hex()


class ModernLEDIndicator(QLabel):
    """现代化LED指示器控件"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFixedSize(40, 40)
        self._state = False
        self._glowing = False

        # 添加呼吸灯效果
        self.glow_timer = QTimer()
        self.glow_timer.timeout.connect(self.toggle_glow)
        self.glow_timer.start(800)  # 每800ms切换一次

        # 动画效果
        self.animation = QPropertyAnimation(self, b"geometry")
        self.animation.setDuration(200)
        self.animation.setEasingCurve(QEasingCurve.OutQuad)

    def setState(self, state):
        """设置LED状态"""
        if self._state != state:
            self._state = state
            self.update()

            # 添加轻微的缩放动画
            current_geometry = self.geometry()
            if state:
                # LED亮起时稍微放大
                self.animation.setStartValue(current_geometry)
                new_geometry = current_geometry.adjusted(-2, -2, 2, 2)
                self.animation.setEndValue(new_geometry)
            else:
                # LED熄灭时恢复原始大小
                self.animation.setStartValue(current_geometry)
                new_geometry = current_geometry.adjusted(2, 2, -2, -2)
                self.animation.setEndValue(new_geometry)

            self.animation.start()

    def toggle_glow(self):
        """切换呼吸灯效果"""
        if self._state:  # 只有在LED亮起时才有呼吸灯效果
            self._glowing = not self._glowing
            self.update()

    def paintEvent(self, event):
        """绘制现代化LED指示器"""
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        center_x = self.width() // 2
        center_y = self.height() // 2
        radius = min(self.width(), self.height()) // 2 - 4

        # 绘制外圈阴影
        shadow_gradient = QLinearGradient(0, 0, 0, self.height())
        shadow_gradient.setColorAt(0, QColor(0, 0, 0, 30))
        shadow_gradient.setColorAt(1, QColor(0, 0, 0, 60))
        painter.setBrush(QBrush(shadow_gradient))
        painter.setPen(Qt.NoPen)
        painter.drawEllipse(center_x - radius - 2, center_y - radius - 2,
                            (radius + 2) * 2, (radius + 2) * 2)

        # 绘制LED主体
        if not self._state:
            # LED亮起 - 绿色渐变
            if self._glowing:
                led_gradient = QLinearGradient(0, 0, 0, self.height())
                led_gradient.setColorAt(0, QColor(34, 197, 94))  # 亮绿色
                led_gradient.setColorAt(0.5, QColor(22, 163, 74))  # 中绿色
                led_gradient.setColorAt(1, QColor(15, 118, 110))  # 深绿色
            else:
                led_gradient = QLinearGradient(0, 0, 0, self.height())
                led_gradient.setColorAt(0, QColor(74, 222, 128))  # 更亮的绿色
                led_gradient.setColorAt(0.5, QColor(34, 197, 94))  # 亮绿色
                led_gradient.setColorAt(1, QColor(22, 163, 74))  # 中绿色
        else:
            # LED熄灭 - 灰色渐变
            led_gradient = QLinearGradient(0, 0, 0, self.height())
            led_gradient.setColorAt(0, QColor(156, 163, 175))  # 浅灰
            led_gradient.setColorAt(0.5, QColor(107, 114, 128))  # 中灰
            led_gradient.setColorAt(1, QColor(75, 85, 99))  # 深灰

        painter.setBrush(QBrush(led_gradient))

        # 绘制边框
        if self._state:
            painter.setPen(QPen(QColor(15, 118, 110), 2))
        else:
            painter.setPen(QPen(QColor(107, 114, 128), 2))

        painter.drawEllipse(center_x - radius, center_y - radius, radius * 2, radius * 2)

        # 绘制高光效果
        if self._state:
            highlight_gradient = QLinearGradient(0, 0, self.width() // 3, self.height() // 3)
            highlight_gradient.setColorAt(0, QColor(255, 255, 255, 180))
            highlight_gradient.setColorAt(1, QColor(255, 255, 255, 0))
            painter.setBrush(QBrush(highlight_gradient))
            painter.setPen(Qt.NoPen)
            painter.drawEllipse(center_x - radius // 2, center_y - radius // 2,
                                radius, radius)


class ValueDisplayLabel(QLabel):
    """数值显示标签"""

    def __init__(self, text="--", unit="", parent=None):
        super().__init__(parent)
        self.unit = unit
        self.setValue(text)
        self.setObjectName("valueLabel")
        self.setAlignment(Qt.AlignCenter)
        self.setMinimumHeight(40)


    def setValue(self, value):
        """设置显示值"""
        if isinstance(value, (int, float)):
            if isinstance(value, float):
                display_text = f"{value:.1f} {self.unit}"
            else:
                display_text = f"{value} {self.unit}"
        else:
            display_text = f"{value} {self.unit}" if value != "--" else "--"

        self.setText(display_text)


class StatusLabel(QLabel):
    """状态显示标签"""

    def __init__(self, text="--", parent=None):
        super().__init__(parent)
        self.setObjectName("statusLabel")
        self.setAlignment(Qt.AlignCenter)
        self.setMinimumHeight(35)
        self.setStatus(text)

    def setStatus(self, status):
        """设置状态"""
        self.setText(status)

        # 根据状态设置不同颜色
        if status in ["按下", "True", "正常"]:
            self.setStyleSheet("""
                QLabel#statusLabel {
                    background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,
                                                stop: 0 #dcfce7, stop: 1 #bbf7d0);
                    border: 1px solid #22c55e;
                    color: #15803d;
                }
            """)
        elif status in ["松开", "False", "异常"]:
            self.setStyleSheet("""
                QLabel#statusLabel {
                    background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,
                                                stop: 0 #fef2f2, stop: 1 #fecaca);
                    border: 1px solid #ef4444;
                    color: #dc2626;
                }
            """)
        else:
            self.setStyleSheet("""
                QLabel#statusLabel {
                    background: #f3f4f6;
                    border: 1px solid #d1d5db;
                    color: #6b7280;
                }
            """)


class MainWindow(QMainWindow):
    """主窗口"""

    def __init__(self):
        super().__init__()
        self.setWindowTitle("🔧 STM32 设备监控系统 - 现代化界面")
        self.resize(700, 700)

        # 应用样式表
        self.setStyleSheet(MODERN_STYLE)

        # 创建串口线程
        self.serial_thread = SerialThread(SERIAL_PORT, BAUD_RATE)
        self.serial_thread.data_received.connect(self.update_device_data)
        self.serial_thread.log_message.connect(self.append_log)
        self.serial_thread.connection_status.connect(self.update_connection_status)

        # 启动串口线程
        self.serial_thread.start()

        # 创建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # 创建主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(15, 15, 15, 15)
        main_layout.setSpacing(15)

        # 创建状态栏
        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)
        self.statusBar.showMessage("🔴 未连接")

        # 创建标签页
        self.tab_widget = QTabWidget()

        # 添加数据显示标签页
        self.create_data_display_tab()

        # 添加命令控制标签页
        self.create_command_control_tab()

        # 添加日志标签页
        self.create_log_tab()

        # 将标签页添加到主布局
        main_layout.addWidget(self.tab_widget)

        # 初始化数据显示
        self.initialize_data_display()

    def initialize_data_display(self):
        """初始化数据显示"""
        # 初始化所有显示值为"--"
        self.temp_value.setValue("--")
        self.counter_value.setValue("--")

        # 设置LED状态为未知
        self.led1_indicator.setState(1)  # 保持视觉上熄灭状态
        self.led2_indicator.setState(1)  # 保持视觉上熄灭状态
        self.led1_status_label.setText("未知")
        self.led2_status_label.setText("未知")
        self.led1_status_label.setStyleSheet("QLabel#statusLabel { color: #6b7280; }")
        self.led2_status_label.setStyleSheet("QLabel#statusLabel { color: #6b7280; }")

        self.button1_label.setStatus("--")
        self.button2_label.setStatus("--")
        self.button3_label.setStatus("--")

        self.uptime_value.setValue("--")
        self.system_temp_value.setValue("--")

    def create_data_display_tab(self):
        """创建数据显示标签页"""
        tab = QWidget()

        # 创建滚动区域
        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        scroll_widget = QWidget()
        layout = QGridLayout(scroll_widget)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        # 温度传感器组
        temp_group = QGroupBox("🌡️ 温度传感器")
        temp_layout = QFormLayout()
        temp_layout.setSpacing(15)

        temp_label = QLabel("当前温度:")
        temp_label.setFont(QFont("", 10, QFont.Bold))
        self.temp_value = ValueDisplayLabel("--", "°C")
        temp_layout.addRow(temp_label, self.temp_value)
        temp_group.setLayout(temp_layout)

        # 计数器组
        pwm_group = QGroupBox("⚙️ 计数器监控")
        pwm_layout = QFormLayout()
        pwm_layout.setSpacing(15)

        counter_label = QLabel("计数值:")
        counter_label.setFont(QFont("", 10, QFont.Bold))
        self.counter_value = ValueDisplayLabel("--", "")
        pwm_layout.addRow(counter_label, self.counter_value)
        pwm_group.setLayout(pwm_layout)

        # LED控制器组
        led_group = QGroupBox("💡 LED 状态指示")
        led_layout = QVBoxLayout()
        led_layout.setSpacing(20)

        # 创建现代化LED指示器
        led1_container = QHBoxLayout()
        led1_title = QLabel("LED 1:")
        led1_title.setFont(QFont("", 10, QFont.Bold))
        self.led1_indicator = ModernLEDIndicator()
        led1_status = QLabel("熄灭")
        led1_status.setObjectName("led1Status")
        led1_container.addWidget(led1_title)
        led1_container.addWidget(self.led1_indicator)
        led1_container.addWidget(led1_status)
        led1_container.addStretch()
        self.led1_status_label = led1_status

        led2_container = QHBoxLayout()
        led2_title = QLabel("LED 2:")
        led2_title.setFont(QFont("", 10, QFont.Bold))
        self.led2_indicator = ModernLEDIndicator()
        led2_status = QLabel("熄灭")
        led2_status.setObjectName("led2Status")
        led2_container.addWidget(led2_title)
        led2_container.addWidget(self.led2_indicator)
        led2_container.addWidget(led2_status)
        led2_container.addStretch()
        self.led2_status_label = led2_status

        led_layout.addLayout(led1_container)
        led_layout.addLayout(led2_container)
        led_group.setLayout(led_layout)

        # 按键状态组
        button_group = QGroupBox("🎮 按键状态")
        button_layout = QVBoxLayout()
        button_layout.setSpacing(15)

        button1_container = QHBoxLayout()
        button1_title = QLabel("按键 1:")
        button1_title.setFont(QFont("", 10, QFont.Bold))
        self.button1_label = StatusLabel("--")
        button1_container.addWidget(button1_title)
        button1_container.addWidget(self.button1_label, 1)

        button2_container = QHBoxLayout()
        button2_title = QLabel("按键 2:")
        button2_title.setFont(QFont("", 10, QFont.Bold))
        self.button2_label = StatusLabel("--")
        button2_container.addWidget(button2_title)
        button2_container.addWidget(self.button2_label, 1)

        button3_container = QHBoxLayout()
        button3_title = QLabel("按键 3:")
        button3_title.setFont(QFont("", 10, QFont.Bold))
        self.button3_label = StatusLabel("--")
        button3_container.addWidget(button3_title)
        button3_container.addWidget(self.button3_label, 1)

        button_layout.addLayout(button1_container)
        button_layout.addLayout(button2_container)
        button_layout.addLayout(button3_container)
        button_group.setLayout(button_layout)

        # 系统状态组
        system_group = QGroupBox("🖥️ 系统状态")
        system_layout = QFormLayout()
        system_layout.setSpacing(15)

        uptime_label = QLabel("运行时间:")
        uptime_label.setFont(QFont("", 10, QFont.Bold))
        self.uptime_value = ValueDisplayLabel("--", "")

        system_temp_label = QLabel("系统温度:")
        system_temp_label.setFont(QFont("", 10, QFont.Bold))
        self.system_temp_value = ValueDisplayLabel("--", "°C")

        system_layout.addRow(uptime_label, self.uptime_value)
        system_layout.addRow(system_temp_label, self.system_temp_value)
        system_group.setLayout(system_layout)

        # 添加到布局
        layout.addWidget(temp_group, 0, 0)
        layout.addWidget(pwm_group, 0, 1)
        layout.addWidget(led_group, 1, 0)
        layout.addWidget(button_group, 1, 1)
        layout.addWidget(system_group, 2, 0, 1, 2)

        # 设置滚动区域
        scroll.setWidget(scroll_widget)
        tab_layout = QVBoxLayout(tab)
        tab_layout.addWidget(scroll)

        # 添加到标签页
        self.tab_widget.addTab(tab, "📊 数据显示")

    def create_command_control_tab(self):
        """创建命令控制标签页"""
        tab = QWidget()
        layout = QVBoxLayout(tab)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        # 命令选择布局
        command_group = QGroupBox("📡 命令发送")
        command_layout = QVBoxLayout()

        # 命令选择行
        command_row = QHBoxLayout()
        command_row.setSpacing(15)

        # 命令选择下拉框
        self.command_combo = QComboBox()
        self.command_combo.addItems([
            "Period (开始/结束检测)",
            "ToggleD1 (切换LED1状态)",
            "ToggleD2 (切换LED2状态)",
            "PWMset (设置PWM占空比)",
            "Counterset (设置计数器上限)",
            "SensorTset (设置温度传感器检测周期)",
            "PWMTset (设置电机检测周期)",
            "LEDTset (设置LED控制器检测周期)",
            "ButtonTset (设置按键状态检测周期)",
            "SystemTset (设置系统状态检测周期)"
        ])
        self.command_combo.setMinimumHeight(40)
        command_row.addWidget(self.command_combo, 2)

        # 值输入框
        self.value_input = QLineEdit()
        self.value_input.setPlaceholderText("输入参数值...")
        self.value_input.setMinimumHeight(40)
        command_row.addWidget(self.value_input, 1)

        # 发送按钮
        self.send_button = QPushButton("📤 发送命令")
        self.send_button.clicked.connect(self.send_command)
        self.send_button.setMinimumHeight(40)
        command_row.addWidget(self.send_button)

        command_layout.addLayout(command_row)
        command_group.setLayout(command_layout)
        layout.addWidget(command_group)

        # 添加快捷命令组
        quick_commands_group = QGroupBox("⚡ 快捷操作")
        quick_commands_layout = QGridLayout()
        quick_commands_layout.setSpacing(15)

        # 开始/结束检测按钮
        period_button = QPushButton("🔄 开始/结束检测")
        period_button.setObjectName("successButton")
        period_button.clicked.connect(lambda: self.send_specific_command(CommandType.PERIOD))
        period_button.setMinimumHeight(45)
        quick_commands_layout.addWidget(period_button, 0, 0)

        # 切换LED1按钮
        toggle_d1_button = QPushButton("💡 切换LED1")
        toggle_d1_button.setObjectName("warningButton")
        toggle_d1_button.clicked.connect(lambda: self.send_specific_command(CommandType.TOGGLE_D1))
        toggle_d1_button.setMinimumHeight(45)
        quick_commands_layout.addWidget(toggle_d1_button, 0, 1)

        # 切换LED2按钮
        toggle_d2_button = QPushButton("💡 切换LED2")
        toggle_d2_button.setObjectName("dangerButton")
        toggle_d2_button.clicked.connect(lambda: self.send_specific_command(CommandType.TOGGLE_D2))
        toggle_d2_button.setMinimumHeight(45)
        quick_commands_layout.addWidget(toggle_d2_button, 0, 2)

        # 添加到主布局
        quick_commands_group.setLayout(quick_commands_layout)
        layout.addWidget(quick_commands_group)

        # 添加参数设置组
        params_group = QGroupBox("⚙️ 参数配置")
        params_layout = QGridLayout()
        params_layout.setSpacing(15)

        # PWM占空比设置
        pwm_label = QLabel("PWM占空比 (0-1):")
        pwm_label.setFont(QFont("", 10, QFont.Bold))
        self.pwm_spinbox = QDoubleSpinBox()
        self.pwm_spinbox.setRange(0, 1)
        self.pwm_spinbox.setSingleStep(0.01)
        self.pwm_spinbox.setValue(0.05)
        self.pwm_spinbox.setMinimumHeight(35)
        pwm_button = QPushButton("✅ 设置")
        pwm_button.clicked.connect(lambda: self.send_value_command(CommandType.PWM_SET, self.pwm_spinbox.value()))
        pwm_button.setMinimumHeight(35)
        params_layout.addWidget(pwm_label, 0, 0)
        params_layout.addWidget(self.pwm_spinbox, 0, 1)
        params_layout.addWidget(pwm_button, 0, 2)

        # 计数器上限设置
        counter_label = QLabel("计数器上限:")
        counter_label.setFont(QFont("", 10, QFont.Bold))
        self.counter_spinbox = QSpinBox()
        self.counter_spinbox.setRange(0, 10000)
        self.counter_spinbox.setValue(1000)
        self.counter_spinbox.setMinimumHeight(35)
        counter_button = QPushButton("✅ 设置")
        counter_button.clicked.connect(
            lambda: self.send_value_command(CommandType.COUNTER_SET, self.counter_spinbox.value()))
        counter_button.setMinimumHeight(35)
        params_layout.addWidget(counter_label, 1, 0)
        params_layout.addWidget(self.counter_spinbox, 1, 1)
        params_layout.addWidget(counter_button, 1, 2)

        # 分割线
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        params_layout.addWidget(line, 2, 0, 1, 3)

        # 检测周期设置标题
        period_title = QLabel("⏱️ 检测周期设置 (毫秒)")
        period_title.setFont(QFont("", 11, QFont.Bold))
        period_title.setStyleSheet("color: #4f46e5; margin: 10px 0;")
        params_layout.addWidget(period_title, 3, 0, 1, 3)

        # 温度传感器检测周期
        sensor_label = QLabel("温度传感器状态检测周期:")
        self.sensor_period_spinbox = QSpinBox()
        self.sensor_period_spinbox.setRange(10, 10000)
        self.sensor_period_spinbox.setValue(1000)
        self.sensor_period_spinbox.setMinimumHeight(35)
        sensor_button = QPushButton("✅ 设置")
        sensor_button.clicked.connect(
            lambda: self.send_value_command(CommandType.SENSOR_TSET, self.sensor_period_spinbox.value()))
        sensor_button.setMinimumHeight(35)
        params_layout.addWidget(sensor_label, 4, 0)
        params_layout.addWidget(self.sensor_period_spinbox, 4, 1)
        params_layout.addWidget(sensor_button, 4, 2)

        #计数值上限设置
        pwm_period_label = QLabel("计数值状态检测周期:")
        self.pwm_period_spinbox = QSpinBox()
        self.pwm_period_spinbox.setRange(10, 10000)
        self.pwm_period_spinbox.setValue(500)
        self.pwm_period_spinbox.setMinimumHeight(35)
        pwm_period_button = QPushButton("✅ 设置")
        pwm_period_button.clicked.connect(
            lambda: self.send_value_command(CommandType.PWM_TSET, self.pwm_period_spinbox.value()))
        pwm_period_button.setMinimumHeight(35)
        params_layout.addWidget(pwm_period_label, 5, 0)
        params_layout.addWidget(self.pwm_period_spinbox, 5, 1)
        params_layout.addWidget(pwm_period_button, 5, 2)

        # LED控制器检测周期
        led_period_label = QLabel("LED状态检测周期:")
        self.led_period_spinbox = QSpinBox()
        self.led_period_spinbox.setRange(10, 10000)
        self.led_period_spinbox.setValue(1000)
        self.led_period_spinbox.setMinimumHeight(35)
        led_period_button = QPushButton("✅ 设置")
        led_period_button.clicked.connect(
            lambda: self.send_value_command(CommandType.LED_TSET, self.led_period_spinbox.value()))
        led_period_button.setMinimumHeight(35)
        params_layout.addWidget(led_period_label, 6, 0)
        params_layout.addWidget(self.led_period_spinbox, 6, 1)
        params_layout.addWidget(led_period_button, 6, 2)

        # 按键状态检测周期
        button_period_label = QLabel("按键状态检测周期:")
        self.button_period_spinbox = QSpinBox()
        self.button_period_spinbox.setRange(10, 10000)
        self.button_period_spinbox.setValue(300)
        self.button_period_spinbox.setMinimumHeight(35)
        button_period_button = QPushButton("✅ 设置")
        button_period_button.clicked.connect(
            lambda: self.send_value_command(CommandType.BUTTON_TSET, self.button_period_spinbox.value()))
        button_period_button.setMinimumHeight(35)
        params_layout.addWidget(button_period_label, 7, 0)
        params_layout.addWidget(self.button_period_spinbox, 7, 1)
        params_layout.addWidget(button_period_button, 7, 2)

        # 系统状态检测周期
        system_period_label = QLabel("系统状态检测周期:")
        self.system_period_spinbox = QSpinBox()
        self.system_period_spinbox.setRange(10, 10000)
        self.system_period_spinbox.setValue(5000)
        self.system_period_spinbox.setMinimumHeight(35)
        system_period_button = QPushButton("✅ 设置")
        system_period_button.clicked.connect(
            lambda: self.send_value_command(CommandType.SYSTEM_TSET, self.system_period_spinbox.value()))
        system_period_button.setMinimumHeight(35)
        params_layout.addWidget(system_period_label, 8, 0)
        params_layout.addWidget(self.system_period_spinbox, 8, 1)
        params_layout.addWidget(system_period_button, 8, 2)

        # 添加到主布局
        params_group.setLayout(params_layout)
        layout.addWidget(params_group)

        # 添加弹性空间
        layout.addStretch()

        # 添加到标签页
        self.tab_widget.addTab(tab, "🎛️ 命令控制")

    def create_log_tab(self):
        """创建日志标签页"""
        tab = QWidget()
        layout = QVBoxLayout(tab)
        layout.setContentsMargins(20, 20, 20, 20)

        # 日志标题和控制
        header_layout = QHBoxLayout()
        log_title = QLabel("📝 系统日志")
        log_title.setFont(QFont("", 12, QFont.Bold))
        log_title.setStyleSheet("color: #374151; margin-bottom: 10px;")
        header_layout.addWidget(log_title)

        header_layout.addStretch()

        # 清除日志按钮
        clear_button = QPushButton("🗑️ 清除日志")
        clear_button.setObjectName("dangerButton")
        clear_button.clicked.connect(self.clear_log)
        clear_button.setMaximumWidth(120)
        header_layout.addWidget(clear_button)

        layout.addLayout(header_layout)

        # 创建日志文本框
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        self.log_text.setMinimumHeight(400)
        layout.addWidget(self.log_text)

        # 添加到标签页
        self.tab_widget.addTab(tab, "📋 系统日志")

    def update_device_data(self, data):
        """更新设备数据显示"""
        device_type = data['device_type']
        device_data = data['data']
        crc_valid = data['crc_valid']

        # 根据设备类型更新相应的数据
        if device_type == DeviceType.TEMP_SENSOR:
            if 'temperature' in device_data:
                self.temp_value.setValue(device_data['temperature'])

        elif device_type == DeviceType.MOTOR_CONTROLLER:
            if 'counter' in device_data:
                self.counter_value.setValue(device_data['counter'])

        elif device_type == DeviceType.LED_CONTROLLER:
            if 'led1' in device_data:
                self.led1_indicator.setState(device_data['led1'])
                self.led1_status_label.setText("亮起" if not device_data['led1'] else "熄灭")
                self.led1_status_label.setStyleSheet(
                    "color: #22c55e; font-weight: bold;" if not device_data['led1'] else
                    "color: #6b7280; font-weight: bold;"
                )
            if 'led2' in device_data:
                self.led2_indicator.setState(device_data['led2'])
                self.led2_status_label.setText("亮起" if not device_data['led2'] else "熄灭")
                self.led2_status_label.setStyleSheet(
                    "color: #22c55e; font-weight: bold;" if not device_data['led2'] else
                    "color: #6b7280; font-weight: bold;"
                )

        elif device_type == DeviceType.BUTTON_STATUS:
            if 'button1' in device_data:
                status = "按下" if device_data['button1'] else "松开"
                self.button1_label.setStatus(status)
            if 'button2' in device_data:
                status = "按下" if device_data['button2'] else "松开"
                self.button2_label.setStatus(status)
            if 'button3' in device_data:
                status = "按下" if device_data['button3'] else "松开"
                self.button3_label.setStatus(status)

        elif device_type == DeviceType.SYSTEM_STATUS:
            if 'uptime' in device_data:
                uptime = device_data['uptime']
                hours = uptime // 3600
                minutes = (uptime % 3600) // 60
                seconds = uptime % 60
                self.uptime_value.setValue(f"{hours:02d}:{minutes:02d}:{seconds:02d}")
            if 'cpu_temp' in device_data:
                self.system_temp_value.setValue(device_data['cpu_temp'])

        # 添加数据接收日志
        status = "✅" if crc_valid else "❌"
        device_name = {
            DeviceType.TEMP_SENSOR: "🌡️ 温度传感器",
            DeviceType.MOTOR_CONTROLLER: "⚙️ PWM控制器",
            DeviceType.LED_CONTROLLER: "💡 LED控制器",
            DeviceType.BUTTON_STATUS: "🎮 按键状态",
            DeviceType.SYSTEM_STATUS: "🖥️ 系统状态"
        }.get(device_type, "❓ 未知设备")

        self.append_log(f"{status} 收到 {device_name} 数据")

    def append_log(self, message):
        """添加日志消息"""
        timestamp = datetime.datetime.now().strftime("%H:%M:%S.%f")[:-3]

        # 根据消息类型设置不同颜色
        if "✅" in message:
            color_style = '<span style="color: #22c55e;">'
        elif "❌" in message:
            color_style = '<span style="color: #ef4444;">'
        elif "📤" in message:
            color_style = '<span style="color: #3b82f6;">'
        elif "🔌" in message:
            color_style = '<span style="color: #8b5cf6;">'
        else:
            color_style = '<span style="color: #f9fafb;">'

        formatted_message = f'<span style="color: #9ca3af;">[{timestamp}]</span> {color_style}{message}</span>'
        self.log_text.append(formatted_message)

        # 滚动到底部
        self.log_text.verticalScrollBar().setValue(
            self.log_text.verticalScrollBar().maximum()
        )

    def clear_log(self):
        """清除日志"""
        self.log_text.clear()
        self.append_log("🗑️ 日志已清除")

    def update_connection_status(self, connected):
        """更新连接状态"""
        if connected:
            self.statusBar.showMessage(f"🟢 已连接到 {SERIAL_PORT}, 波特率 {BAUD_RATE}")
            self.send_button.setEnabled(True)
        else:
            self.statusBar.showMessage("🔴 未连接")
            self.send_button.setEnabled(False)

    def send_command(self):
        """发送命令"""
        command_text = self.command_combo.currentText()
        value_text = self.value_input.text().strip()

        # 确定命令类型
        command_mapping = {
            "Period (开始/结束检测)": CommandType.PERIOD,
            "ToggleD1 (切换LED1状态)": CommandType.TOGGLE_D1,
            "ToggleD2 (切换LED2状态)": CommandType.TOGGLE_D2,
            "PWMset (设置PWM占空比)": CommandType.PWM_SET,
            "Counterset (设置计数器上限)": CommandType.COUNTER_SET,
            "SensorTset (设置温度传感器检测周期)": CommandType.SENSOR_TSET,
            "PWMTset (设置PWM控制器检测周期)": CommandType.PWM_TSET,
            "LEDTset (设置LED控制器检测周期)": CommandType.LED_TSET,
            "ButtonTset (设置按键状态检测周期)": CommandType.BUTTON_TSET,
            "SystemTset (设置系统状态检测周期)": CommandType.SYSTEM_TSET
        }

        command_type = command_mapping.get(command_text, None)
        if not command_type:
            self.append_log("❌ 错误: 未知命令")
            return

        # 解析值
        value = None
        if value_text:
            try:
                # 根据命令类型解析值
                if command_type in [CommandType.PWM_SET]:
                    value = float(value_text)
                elif command_type in [CommandType.COUNTER_SET,
                                      CommandType.SENSOR_TSET,
                                      CommandType.PWM_TSET,
                                      CommandType.LED_TSET,
                                      CommandType.BUTTON_TSET,
                                      CommandType.SYSTEM_TSET]:
                    value = int(value_text)
                else:
                    value = value_text
            except ValueError:
                self.append_log(f"❌ 错误: 无法解析值 '{value_text}'")
                return

        # 发送命令
        self.serial_thread.send_command(command_type, value)

        # 如果是结束检测命令，清空数据显示
        if command_type == CommandType.PERIOD and value == 0:
            self.initialize_data_display()

        # 如果是设置值的命令，更新相应的输入框
        if command_type == CommandType.PWM_SET and value is not None:
            self.pwm_spinbox.setValue(value)
        elif command_type == CommandType.COUNTER_SET and value is not None:
            self.counter_spinbox.setValue(value)
        elif command_type == CommandType.SENSOR_TSET and value is not None:
            self.sensor_period_spinbox.setValue(value)
        elif command_type == CommandType.PWM_TSET and value is not None:
            self.pwm_period_spinbox.setValue(value)
        elif command_type == CommandType.LED_TSET and value is not None:
            self.led_period_spinbox.setValue(value)
        elif command_type == CommandType.BUTTON_TSET and value is not None:
            self.button_period_spinbox.setValue(value)
        elif command_type == CommandType.SYSTEM_TSET and value is not None:
            self.system_period_spinbox.setValue(value)

    def send_specific_command(self, command_type):
        """发送特定命令"""
        self.serial_thread.send_command(command_type)
        # 如果是结束检测命令，清空数据显示
        if command_type == CommandType.PERIOD:
            self.initialize_data_display()

    def send_value_command(self, command_type, value):
        """发送带值的命令"""
        self.serial_thread.send_command(command_type, value)
        self.append_log(f"📤 发送命令: {command_type.value} {value}")

    def closeEvent(self, event):
        """关闭窗口时清理资源"""
        # 停止串口线程
        self.serial_thread.close()
        self.serial_thread.wait()

        event.accept()


if __name__ == "__main__":
    app = QApplication(sys.argv)

    # 设置应用程序字体
    font = QFont("Segoe UI", 9)
    app.setFont(font)

    window = MainWindow()
    window.show()
    sys.exit(app.exec_())